home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / LANG / PROLOG / BP330 / !BinPro330 / progs / tetris < prev    next >
Text File  |  1993-10-06  |  7KB  |  332 lines

  1. % Tetris en Prolog (C) Paul Tarau 1989
  2.  
  3. % version avec evaluation complete mais non-optimisee
  4. % on minimise "l'energie" du relief = la somme des
  5. % hauteurs des briques, y compris les espaces vides
  6. % (apres une chutte hypothetique)
  7.  
  8. % tetris9.pro
  9. % FAITES: d.
  10.  
  11. :-op(900,yfx,:).
  12.  
  13. max(20,10). % L,C
  14.  
  15. % interface ALS
  16.  
  17. scr_clear:-for(_,1,60),nl,fail; true.
  18.  
  19. scr_send(p(L0,C0),Char):-
  20.   L is L0+1, C is C0+1,
  21.   put(27),
  22.   cwrite('['),cwrite(L),
  23.   cwrite(';'),cwrite(C),
  24.   cwrite('H'),
  25.   put(Char).
  26.  
  27. scr_rec(_):-fail.
  28.  
  29. rtest:-for(I,1,50),random(20,R),cwrite(R),nl,fail.
  30.  
  31. random(Max,R):-
  32.     random(N),
  33.     R is N mod Max.  
  34.  
  35. cputime(X):-statistics(runtime,[X,_]).
  36.  
  37. dir_depl(0,p( 0, 1)).   % right -77
  38. dir_depl(1,p( 1, 0)).   % down -80
  39. dir_depl(2,p( 0,-1)).   % left -75
  40. dir_depl(3,p(-1, 0)).   % up -72
  41.  
  42. usr_dir(-77,0).
  43. usr_dir(-80,1).
  44. usr_dir(-75,2).
  45. usr_dir(-72,3).
  46. usr_dir(13,-1).
  47. usr_dir(27,0):-fin.
  48.  
  49.  
  50. % mouvement
  51.  
  52. next(Dir,p(L1,C1),p(L2,C2)):-
  53.         max(MaxL,MaxC),
  54.         dir_depl(Dir,p(DL,DC)),
  55.         L2 is L1+DL,C2 is C1+DC,
  56.         L2>=0,L2<MaxL,C2>=0,C2<MaxC.
  57.  
  58. select(-1,bloc(T,O1,P),bloc(T,O2,P)):-!,
  59.         O2 is (O1+1) mod 4.
  60. select(Dir,bloc(T,O,P1),bloc(T,O,P2)):-
  61.         next(Dir,P1,P2).
  62.  
  63. /* lecture d'une direction: chutte par defaut */
  64. scr_dir(1).
  65. /*
  66. scr_dir(D):-
  67.         cputime(T0),
  68.         repeat,
  69.         ( scr_rec(C)->usr_dir(C,D)
  70.         ; cputime(T1), DeltaT is T1-T0,DeltaT>0.20,D is 1
  71.         ).
  72. */
  73.  
  74. % objets
  75.  
  76. /* image(Type,[Dir|Ds]) */
  77. image(0,[0,1,0]).       % z.
  78. image(1,[1,0,1]).       % -z.
  79. image(2,[0,1,1]).       % l.
  80. image(3,[0,0,1]).       % -l.
  81. image(4,[1,1,1]).       % i.
  82. image(5,[0,1,2,3]).     % carre.
  83. image(6,[0,0,2,1]).     % a.
  84.  
  85. bloc2briques(B,Qs):-
  86.         B=bloc(Type,_,_),
  87.         image(Type,Dirs),
  88.         bloc2briques(Dirs,B,Ps),
  89.         sort(Ps,Qs).
  90.  
  91. bloc2briques([],bloc(_,_,P),[P]):-!.
  92. bloc2briques([D|Ds],bloc(T,O,P1),[P1|Ps]):-
  93.         Dir is (O+D) mod 4,
  94.         next(Dir,P1,P2),
  95.         !,
  96.         bloc2briques(Ds,bloc(T,O,P2),Ps).
  97.  
  98. afficher_briques([],_):-!.
  99. afficher_briques([P|Ps],Image):-
  100.         scr_send(P,Image),
  101.         !,
  102.         afficher_briques(Ps,Image).
  103.  
  104. deplacer_briques(Old,New):- 
  105.                 "*"=[Brique],
  106.         afficher_briques(Old,32),
  107.         afficher_briques(New,Brique).     
  108.  
  109. tester_briques(Briques,Relief):-
  110.         member(X,Briques),member(X,Relief)->fail
  111. ;       true.
  112.  
  113. deplacer_bloc(B1,B2,R):-
  114.         bloc2briques(B2,New),
  115.         tester_briques(New,R),
  116.         bloc2briques(B1,Old),
  117.         deplacer_briques(Old,New).
  118.  
  119. comprimer_relief(N1:R1,N2:R2):-
  120.         max(MaxL,MaxC),
  121.         bagof(Plein:L-Cs,
  122.         Len^(
  123.           bagof(C,member(p(L,C),R1),Cs),
  124.           length(Cs,Len),
  125.           ( Len=MaxC->Plein=1
  126.           ; Plein=0
  127.           )
  128.         ),
  129.         BLCs),
  130.         !,
  131.         eliminer(BLCs,LCs,N),
  132.         !,
  133.         N>0,N2 is N1+N,
  134.         elements(LCs,R2).
  135.  
  136. score(N):-
  137.         max(MaxL,MaxC),
  138.         Score is N*MaxC,MesL is MaxL+1,
  139.         scr_send(p(MesL,0),32), % 7 if not quiet
  140.     cwrite('Score:'),cwrite(Score).
  141.  
  142. element(LCs,p(L,C)):-member(L-Cs,LCs),member(C,Cs).
  143.  
  144. elements(LCs,Ps):-findall(P,element(LCs,P),Ps).
  145.  
  146. eliminer([],[],0):-!.
  147. eliminer([L|Ls],Rs2,N2):-
  148.         eliminer(Ls,Rs1,N1),
  149.         enlever(L,Rs1,Rs2,N1,N2).
  150.  
  151. enlever(1:_,Rs,Rs,N1,N2):-N2 is N1+1,!.
  152. enlever(0:L-Cs,Rs1,[L1-Cs|Rs1],N,N):-L1 is L+N.
  153.  
  154. touche(p(L,_),_):-max(M,_),L>=M,!. % no free space down
  155. touche(P,Ps):-member(P,Ps),!.
  156.  
  157.  
  158. % essayer
  159.  
  160. essayer_animer_bloc(B,N:R1,N:R2):-
  161.     bloc2briques(B,Ps),
  162.     essayer_descendre_bloc(Ps,R1,R2).
  163.  
  164. essayer_descendre_bloc(Ps1,R1,R2):-
  165.         essayer_changer_bloc(Ps1,Ps2,R1),
  166.         !,
  167.         essayer_descendre_bloc(Ps2,R1,R2).
  168. essayer_descendre_bloc(Ps,R1,R3):-       
  169.         det_append(Ps,R1,R2),
  170.         !,
  171.         essayer_reduire(R2,R3).
  172.  
  173. essayer_reduire(R1,R2):-
  174.         comprimer_relief(0:R1,_:R2),
  175.         !.
  176. essayer_reduire(R,R).
  177.  
  178. descendre([],[],MaxL):-!.
  179. descendre([p(L1,C)|Ps1],[p(L2,C)|Ps2],MaxL):-
  180.     L2 is L1+1,
  181.     L2<MaxL,
  182.     !,
  183.     descendre(Ps1,Ps2,MaxL).
  184.  
  185. essayer_changer_bloc(Bs1,Bs2,R):-
  186.     max(MaxL,_),
  187.     descendre(Bs1,Bs2,MaxL),
  188.   ( member(X,Bs2),member(X,R)->fail
  189.   ; true
  190.     ),
  191.   !.
  192.  
  193.  
  194. % evaluer
  195.  
  196. minimiser_energie_relief(B0,_,N:R1):-
  197.         B0=bloc(Type,_,_),
  198.         re_init_best(B0),
  199.         generer_bloc(Type,B),
  200.         essayer_animer_bloc(B,N:R1,_:R2),
  201.         energie(R2,Val),
  202.         the_best(OldB,OldVal),
  203.         Val<OldVal,
  204.         set_best(B,Val),
  205.         deplacer_bloc(OldB,B,R1),
  206.         max(MaxL,_),L is MaxL+2,
  207.     [Prompt]=">",
  208.         scr_send(p(L,0),Prompt),
  209.         statistics(global_stack,Stat),statistics(bboard,BBStat),
  210.         write('Energie':Val),write(' Heap':Stat),write('    '),
  211.     write('Blackboard':BBStat),write('     '),
  212.         fail.
  213. minimiser_energie_relief(_,B,_):-
  214.         the_best(B,_).
  215.  
  216. generer_bloc(Type,bloc(Type,Orientation,p(3,C))):-
  217.         max(_,MaxC),
  218.         MaxC1 is MaxC-1,
  219.         for(C,0,MaxC1),
  220.         for(Orientation,0,3).
  221.  
  222. surface(R1,S):-
  223.         findall(C-Ls,
  224.               setof(L,member(p(L,C),R1),Ls),
  225.         CLs),
  226.         findall(p(L1,C0),
  227.            (member(C0-[L0|_],CLs),L1 is L0-1),
  228.         S).
  229.  
  230. energie(Briques,G):-
  231.         surface(Briques,S),
  232.         energie(S,0,G).
  233.  
  234. energie([],G,G):-!.
  235. energie([p(L,_)|Ps],G1,G3):-
  236.         max(MaxL,_),
  237.         G2 is G1+((MaxL-L)*(MaxL-L+1) // 2),
  238.         !,
  239.         energie(Ps,G2,G3).
  240.  
  241.  
  242. init_best:-bb_let(tetris,best(bloc(3,0,p(1,1)),99999)).
  243.  
  244. re_init_best(B):-set_best(B,99999).
  245.  
  246. set_best(Bloc,V):-bb_set(tetris,best(Bloc,V)).
  247.  
  248. the_best(Bloc,V):-bb_val(tetris,best(Bloc,V)).
  249.  
  250. % animer
  251.  
  252. impact(B,N:R1,N:R2):-
  253.         bloc2briques(B,Ps),       
  254.         member(p(L,C),Ps),L1 is L+1,
  255.         touche(p(L1,C),R1),
  256.         det_append(Ps,R1,R2),
  257.         !.
  258.  
  259. reduire(N1:R1,N2:R2):-
  260.         comprimer_relief(N1:R1,N2:R2),
  261.         deplacer_briques(R1,R2),
  262.         score(N2),
  263.         !.
  264. reduire(R,R).
  265.  
  266.  
  267. changer_bloc(B1,B2,_:R):-
  268.         scr_dir(Dir),
  269.         select(Dir,B1,B2),
  270.         deplacer_bloc(B1,B2,R),
  271.         !.
  272. changer_bloc(B,B,_).
  273.  
  274. animer_bloc(B,R1,R3):-impact(B,R1,R2),!,
  275.         reduire(R2,R3).
  276. animer_bloc(B1,R1,R2):-
  277.         changer_bloc(B1,B2,R1),
  278.         !,
  279.         animer_bloc(B2,R1,R2).
  280.  
  281.  
  282. % jouer
  283.  
  284. plein(Relief):-member(p(L,_),Relief), L=<5. % no free space up
  285.  
  286. creer_bloc(bloc(Type,0,p(5,MidC))):-!,
  287.         max(_,MaxC),MidC is MaxC // 2,
  288.         random(7,Type).
  289.  
  290. meilleur_bloc(jeu,B0,B0,_):-!.
  291. meilleur_bloc(demo,B0,B,NR):-
  292.         minimiser_energie_relief(B0,B,NR).
  293.  
  294. jouer(_,_:Relief):-plein(Relief),!.
  295. jouer(Mode,Relief1):-
  296.         creer_bloc(B0),
  297.         meilleur_bloc(Mode,B0,B,Relief1),
  298.         !,
  299.     gc_call( 
  300.         animer_bloc(B,Relief1,Relief2)
  301.     )
  302.     ,
  303.         !,
  304.         jouer(Mode,Relief2).
  305.  
  306. init(N:[]):-
  307.         scr_clear,
  308.         max(MaxL,MaxC),[Board]="#",
  309.         init_best,
  310.         (for(L,6,MaxL),scr_send(p(L,MaxC),Board),fail; true),
  311.         (for(C,0,MaxC),scr_send(p(MaxL,C),Board),fail; true),
  312.         N=0,score(N),
  313.         !.
  314.  
  315. fin :- 
  316.         max(L,_),L1 is L+3,
  317.         scr_send(p(L1,0),32),nl,
  318.         abort.
  319.  
  320. go(Mode):-
  321.         init(State),
  322.         jouer(Mode,State),
  323.         fin.
  324.  
  325. g:-go(jeu).
  326.  
  327. go:-go(demo).
  328.  
  329. d:-go.
  330.  
  331.